unit MainUnit;

interface

uses
  SysUtils, Types, Classes, Variants, QTypes, QGraphics, QControls, QForms,
  QDialogs, QStdCtrls, QMenus, QComCtrls, QExtCtrls, datacontainer, diagramfactory, StdVarChartUnit, SSBRecruitChartUnit,
  qqplot, kolmogorovplot, yearclassplot, yearclassNplot,
  logratioschartunit, bootplots, retroplots, QImgList, ifmactionprotocolunit, aifmviewunit, pgchartunit, pgdiagramunit, ifmprintercanvasunit,
  qprinters, stdcommandsunit, TasacsTrendCommandIds, pgdynamiccollection, apgabstractunit, xmldoc, xmlintf, xercesxmldom,
  pagedviewunit, pgdataobjectunit, ifmdialogunit, apgabstracttypesunit, Residualschartunit, contnrs, ifmmemoryunit, math;

type
   TfrmTasacsTrend = class;


   TasacsDiagrams = class(PgDynamicCollectionImpl, IDiagramParent, ITasacsDiagramParent)
   private
      // IDiagramParent
      function GetActiveDiagramTargetView : IPgDiagramTargetView;
      // ITasacsDiagramParent
      function GetYearClassNDiagram(iDgr : Integer) : TasacsDiagram;
   protected
      procedure Open(Node : IXMLNode); override;
      procedure Save(var Node : IXMLNode); override;
   public
      m_StdCharts : TObjectList;
      m_StdDiagram : PgDiagram;
      m_SSBRecruitsChart : PgChart;
      m_SSBRecruitsDiagram : PgDiagram;
      m_ResidualUCharts : TObjectList;
      m_ResidualWCharts : TObjectList;
      m_ResidualPhiCharts : TObjectList;
      m_ResidualWeightCharts : TObjectList;
      m_ResidualDiagrams : TObjectList;
      m_LogRatiosCharts : TObjectList;
      m_LogRatiosDiagrams : TObjectList;
      m_QQCharts : TObjectList;
      m_QQDiagrams : TObjectList;
      m_KolCharts : TObjectList;
      m_KolDiagrams : TObjectList;
      m_YearClassCharts : TObjectList;
      m_YearClassDiagrams : TObjectList;
      m_YearClassNCharts : TObjectList;
      m_YearClassNDiagrams : TObjectList;
      m_BootCharts : TObjectList;
      m_BootDiagram : PgDiagram;
      m_RetroCharts : TObjectList;
      m_RetroDiagram : PgDiagram;
      frmTasacsTrend : TfrmTasacsTrend;
      destructor Destroy; override;
      constructor Create(AOwner : TComponent);
   end; // TasacsDiagrams


  TfrmTasacsTrend = class(TForm, TActionTarget, IVisibleNodeOwner)
    tvPlotType: TTreeView;
    Splitter1: TSplitter;
    m_Images: TImageList;
    m_StatusBar: TStatusBar;
    FrmPanel: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FrmPanelResize(Sender: TObject);
    procedure tvPlotTypeClick(Sender: TObject);
  private
      m_RunDir : string;
      m_Diagrams : TasacsDiagrams;
      m_ResidualsView : PagedView;
      m_QQView : PagedView;
      m_KolView : PagedView;
      m_LogRatiosView : PagedView;
      m_YearclassView : PagedView;
      m_YearclassNView : PagedView;
      m_ConfigFile : string;

      m_DataContainer : TasacsDataContainer;
      m_ExtentMapper : TExtentMapper;
      m_MainTarget : TActionTargetOwnerDelegation;
      m_ActionManager : TActionManager;
      m_handlingUpdate : Boolean;
    { Private declarations }
      // IVisibleNodeOwner
      function GetActiveView : TView;
      procedure SaveConfiguration;
      procedure OpenConfiguration;
      procedure UpdatePhase();

      function GetExtentMapper : TExtentMapper;
      function GetWorkspaceTopLeft(Control : TControl) : TPoint;
      function GetActionManager : IActionManager;
      function GetImages : TImageList;
      procedure OnVisibleNodeUpdated(VisibleNodeComponent : IVisibleNodeComponent);
      procedure OnVisibleNodeDeleted(VisibleNodeComponent, ParentNodeComponent : IVisibleNodeComponent);
      procedure OnViewableComponentAdded(ViewComponent, ViewParent : IVisibleNodeComponent; UserSelectName : Boolean = false);
      // TActionTarget
      procedure Execute(Action : PgDataAction; var Handled, Recurse : Boolean);
      procedure Update(Action : PgDataAction; var Handled, Recurse : Boolean); reintroduce;
      procedure GetContextActions(var ActionIds : TList);
      function GetSubTargetCount : Integer;
      function GetSubTarget(I : Integer) : TActionTarget;
  public
    { Public declarations }
    destructor Destroy; override;
  end;

var
  frmTasacsTrend: TfrmTasacsTrend;

implementation

{$R *.xfm}
{$R res\TasacsTrendRes.res}
{$R c:\projects\pg2sr\dev\include\res\Std.res}


constructor TasacsDiagrams.Create(AOwner : TComponent);
var
   I : StdVar;
   B : TBootType;
   R : TRetroType;
begin
   inherited Create(AOwner, nil, '', -1, '', '', false, false, false);
   frmTasacsTrend := AOwner as TfrmTasacsTrend;
   m_StdCharts := TObjectList.Create;
   for I := stdRecruits  to stdLandings do
      m_StdCharts.Add(nil);
   m_ResidualUCharts := TObjectList.Create;
   m_ResidualWCharts := TObjectList.Create;
   m_ResidualPhiCharts := TObjectList.Create;
   m_ResidualWeightCharts := TObjectList.Create;
   m_ResidualDiagrams := TObjectList.Create;
   m_LogRatiosCharts := TObjectList.Create;
   m_LogRatiosDiagrams := TObjectList.Create;
   m_YearClassCharts := TObjectList.Create;
   m_YearClassDiagrams := TObjectList.Create;
   m_YearClassNCharts := TObjectList.Create;
   m_YearClassNDiagrams := TObjectList.Create;
   m_QQCharts := TObjectList.Create;
   m_QQDiagrams := TObjectList.Create;
   m_KolCharts := TObjectList.Create;
   m_KolDiagrams := TObjectList.Create;
   m_BootCharts := TObjectList.Create;
   for B := btSSB  to btBanana do
      m_BootCharts.Add(nil);
   m_RetroCharts := TObjectList.Create;
   for R := rtSSB  to rtRecruit do
      m_RetroCharts.Add(nil);
end; // TasacsDiagrams.Create


function TasacsDiagrams.GetYearClassNDiagram(iDgr : Integer) : TasacsDiagram;
begin
   Result := TasacsDiagram(m_YearClassNDiagrams[iDgr]);
end; // TasacsDiagrams.GetFirstYearClassNDiagram


destructor TasacsDiagrams.Destroy;
begin
   m_StdCharts.Free;
   m_StdDiagram.Free;
   m_SSBRecruitsChart.Free;
   m_SSBRecruitsDiagram.Free;;
   m_ResidualUCharts.Free;
   m_ResidualWCharts.Free;
   m_ResidualPhiCharts.Free;
   m_ResidualWeightCharts.Free;
   m_ResidualDiagrams.Free;
   m_QQCharts.Free;
   m_QQDiagrams.Free;
   m_KolCharts.Free;
   m_KolDiagrams.Free;
   m_LogRatiosCharts.Free;
   m_LogRatiosDiagrams.Free;
   m_YearClassCharts.Free;
   m_YearClassDiagrams.Free;
   m_YearClassNCharts.Free;
   m_YearClassNDiagrams.Free;
   m_BootCharts.Free;
   m_BootDiagram.Free;
   m_RetroCharts.Free;
   m_RetroDiagram.Free;
   inherited;
end; // TasacsDiagrams.Destroy


function TasacsDiagrams.GetActiveDiagramTargetView : IPgDiagramTargetView;
begin
   if frmTasacsTrend <> nil then
      with frmTasacsTrend do
      if GetActiveView <> nil then
         if supports(GetActiveView, IPgDiagramTargetView) then
            Result := GetActiveView as IPgDiagramTargetView
         else
            Result := (GetActiveView as IPagedView).ActiveView as IPgDiagramTargetView;
end; // TasacsDiagrams.GetActiveDiagramTargetView


const
   s_StdChart = 'StdChart';
   s_StdDiagram = 'StdDiagram';
   s_SSBRecruitsChart = 'RecruitsChart';
   s_SSBRecruitsDiagram = 'RecruitsDgr';
   s_ResidualWChart = 'ResidualWChart';
   s_ResidualUChart = 'ResidualUChart';
   s_ResidualPhiChart = 'ResidualPhiChart';
   s_ResidualWeightChart = 'ResidualWeightChart';
   s_ResidualDiagram = 'ResidualDgr';
   s_LogRatiosChart = 'LogRatiosChart';
   s_LogRatiosDiagram = 'LogRatiosDgr';
   s_YearClassChart = 'YearClassChart';
   s_YearClassDiagram = 'YearClassDgr';
   s_YearClassNChart = 'YearClassNChart';
   s_YearClassNDiagram = 'YearClassNDgr';
   s_QQChart = 'QQChart';
   s_QQDiagram = 'QQDgr';
   s_KolChart = 'KolChart';
   s_KolDiagram = 'KolDgr';
   s_BootChart = 'BootChart';
   s_BootDiagram = 'BootDiagram';
   s_RetroChart = 'RetroChart';
   s_RetroDiagram = 'RetroDiagram';


procedure TasacsDiagrams.Open(Node : IXMLNode);
var
   iVar : StdVar;
   iBoot : TBootType;
   iRetro : TretroType;
   iDs, iAge, NumAges, iCohort, iYearClassDgr : Integer;
   dsc : DataSourceContainer;
begin
   for iVar := stdRecruits to stdLandings do
      OpenChild(Node, PgChart(m_StdCharts[ord(iVar) - ord(stdRecruits)]), s_StdChart + inttostr(ord(iVar) + 1));
   OpenChild(Node, m_StdDiagram, s_StdDiagram);
   OpenChild(Node, m_SSBRecruitsChart, s_SSBRecruitsChart);
   OpenChild(Node, m_SSBRecruitsDiagram, s_SSBRecruitsDiagram);
   for iDs := 0 to frmTasacsTrend.m_DataContainer.Ds.count - 1 do
   begin
      OpenChild(Node, PgChart(m_ResidualUCharts[iDs]), s_ResidualUChart + inttostr(ord(iDs) + 1));
      OpenChild(Node, PgChart(m_ResidualWCharts[iDs]), s_ResidualWChart + inttostr(ord(iDs) + 1));
      OpenChild(Node, PgChart(m_ResidualPhiCharts[iDs]), s_ResidualPhiChart + inttostr(ord(iDs) + 1));
      OpenChild(Node, PgChart(m_ResidualWeightCharts[iDs]), s_ResidualWeightChart + inttostr(ord(iDs) + 1));
      OpenChild(Node, PgDiagram(m_ResidualDiagrams[iDs]), s_ResidualDiagram + inttostr(ord(iDs) + 1));
      dsc := DataSourceContainer(frmTasacsTrend.m_DataContainer.DS[iDs]);
      NumAges := FloatMatrix(dsc.DsData[ord(dsObs)]).GetSize(2);
      for iAge := 0 to NumAges - 1 - 2 do
         OpenChild(Node, PgChart(TList(m_LogRatiosCharts[iDs])[iAge]), s_LogRatiosChart + inttostr(ord(iDs) + 1) + inttostr(iAge + 1));
      OpenChild(Node, PgDiagram(m_LogRatiosDiagrams[iDs]), s_LogRatiosDiagram + inttostr(ord(iDs) + 1));
      OpenChild(Node, PgChart(m_QQCharts[iDs]), s_QQChart + inttostr(ord(iDs) + 1));
      OpenChild(Node, PgDiagram(m_QQDiagrams[iDs]), s_QQDiagram + inttostr(ord(iDs) + 1));
      OpenChild(Node, PgChart(m_KolCharts[iDs]), s_KolChart + inttostr(ord(iDs) + 1));
      OpenChild(Node, PgDiagram(m_KolDiagrams[iDs]), s_KolDiagram + inttostr(ord(iDs) + 1));
   end;
   for iCohort := 0 to frmTasacsTrend.m_DataContainer.NumCohorts - 1 do
   begin
      OpenChild(Node, PgChart(m_YearClassCharts[iCohort]), s_YearClassChart + inttostr(iCohort + 1));
      OpenChild(Node, PgChart(m_YearClassNCharts[iCohort]), s_YearClassNChart + inttostr(iCohort + 1));
   end;
   for iYearClassDgr := 0 to frmTasacsTrend.m_DataContainer.NumYearClassDiagrams - 1 do
   begin
      OpenChild(Node, PgDiagram(m_YearClassDiagrams[iYearClassDgr]), s_YearClassDiagram + inttostr(iYearClassDgr + 1));
      OpenChild(Node, PgDiagram(m_YearClassNDiagrams[iYearClassDgr]), s_YearClassNDiagram + inttostr(iYearClassDgr + 1));
   end;
   for iBoot := btSSB to btBanana do
      OpenChild(Node, PgChart(m_BootCharts[ord(iBoot) - ord(btSSB)]), s_BootChart + inttostr(ord(iBoot) + 1));
   for iretro := rtSSB to rtRecruit do
      OpenChild(Node, PgChart(m_RetroCharts[ord(iRetro) - ord(rtSSB)]), s_RetroChart + inttostr(ord(iRetro) + 1));
   OpenChild(Node, m_RetroDiagram, s_RetroDiagram);
end; // TasacsDiagrams.Open


procedure TasacsDiagrams.Save(var Node : IXMLNode);
var
   iVar : StdVar;
   iBoot : TBootType;
   iRetro : TRetroType;
   iDs, iAge, NumAges, iCohort, iYearClassDgr : Integer;
   dsc : DataSourceContainer;
begin
   for iVar := stdRecruits  to stdLandings do
      SaveChild(Node, PgChart(m_StdCharts[ord(iVar) - ord(stdRecruits)]), s_StdChart + inttostr(ord(iVar) + 1));
   SaveChild(Node, m_StdDiagram, s_StdDiagram);
   SaveChild(Node, m_SSBRecruitsChart, s_SSBRecruitsChart);
   SaveChild(Node, m_SSBRecruitsDiagram, s_SSBRecruitsDiagram);
   for iDs := 0 to frmTasacsTrend.m_DataContainer.Ds.count - 1 do
   begin
      SaveChild(Node, PgChart(m_ResidualUCharts[iDs]), s_ResidualUChart + inttostr(ord(iDs) + 1));
      SaveChild(Node, PgChart(m_ResidualWCharts[iDs]), s_ResidualWChart + inttostr(ord(iDs) + 1));
      SaveChild(Node, PgChart(m_ResidualPhiCharts[iDs]), s_ResidualPhiChart + inttostr(ord(iDs) + 1));
      SaveChild(Node, PgChart(m_ResidualWeightCharts[iDs]), s_ResidualWeightChart + inttostr(ord(iDs) + 1));
      SaveChild(Node, PgDiagram(m_ResidualDiagrams[iDs]), s_ResidualDiagram + inttostr(ord(iDs) + 1));
      dsc := DataSourceContainer(frmTasacsTrend.m_DataContainer.DS[iDs]);
      NumAges := FloatMatrix(dsc.DsData[ord(dsObs)]).GetSize(2);
      for iAge := 0 to NumAges - 1 - 2 do
         SaveChild(Node, PgChart(TList(m_LogRatiosCharts[iDs])[iAge]), s_LogRatiosChart + inttostr(ord(iDs) + 1) + inttostr(iAge + 1));
      SaveChild(Node, PgDiagram(m_LogRatiosDiagrams[iDs]), s_LogRatiosDiagram + inttostr(ord(iDs) + 1));
      SaveChild(Node, PgChart(m_QQCharts[iDs]), s_QQChart + inttostr(ord(iDs) + 1));
      SaveChild(Node, PgDiagram(m_QQDiagrams[iDs]), s_QQDiagram + inttostr(ord(iDs) + 1));
      SaveChild(Node, PgChart(m_KolCharts[iDs]), s_KolChart + inttostr(ord(iDs) + 1));
      SaveChild(Node, PgDiagram(m_KolDiagrams[iDs]), s_KolDiagram + inttostr(ord(iDs) + 1));
   end;
   for iCohort := 0 to frmTasacsTrend.m_DataContainer.NumCohorts - 1 do
   begin
      SaveChild(Node, PgChart(m_YearClassCharts[iCohort]), s_YearClassChart + inttostr(iCohort + 1));
      SaveChild(Node, PgChart(m_YearClassNCharts[iCohort]), s_YearClassNChart + inttostr(iCohort + 1));
   end;
   for iYearClassDgr := 0 to frmTasacsTrend.m_DataContainer.NumYearClassDiagrams - 1 do
   begin
      SaveChild(Node, PgDiagram(m_YearClassDiagrams[iYearClassDgr]), s_YearClassDiagram + inttostr(iYearClassDgr + 1));
      SaveChild(Node, PgDiagram(m_YearClassNDiagrams[iYearClassDgr]), s_YearClassNDiagram + inttostr(iYearClassDgr + 1));
   end;
   for iBoot := btSSB to btBanana do
      SaveChild(Node, PgChart(m_BootCharts[ord(iBoot) - ord(btSSB)]), s_BootChart + inttostr(ord(iBoot) + 1));
   SaveChild(Node, m_BootDiagram, s_BootDiagram);
   for iretro := rtSSB to rtRecruit do
      SaveChild(Node, PgChart(m_RetroCharts[ord(iRetro) - ord(rtSSB)]), s_RetroChart + inttostr(ord(iRetro) + 1));
   SaveChild(Node, m_RetroDiagram, s_RetroDiagram);
end; // TasacsDiagrams.Save


const s_TasacsTrendSetupDoc = 'TasacsTrendResSetup';

procedure TfrmTasacsTrend.FormCreate(Sender: TObject);
var
   iVar : StdVar;
   iBoot : TBootType;
   iRetro : TRetroType;
   iDs, iAge, iCohort, iDgr, iCohortFrom, iCohortTo : Integer;
   DgrCapt : string;
   dsc : DataSourceContainer;
   NumAges : Integer;
begin
   DecimalSeparator := '.';
   m_RunDir := '';
   if ParamCount = 1 then
      m_RunDir := ParamStr(1);
   m_ConfigFile := 'Config.cfg';
   m_DataContainer := TasacsDataContainer.Create(m_RunDir);
   if m_DataContainer.Error <> '' then
      MessageDlg(m_DataContainer.Error, mtError, [mbOK], 0);
   m_handlingUpdate := false;
   m_ExtentMapper := TExtentMapper.Create(Self, GetPaintDevice);
   m_StatusBar.AutoHint := true;

   m_ResidualsView := PagedView.Create(Self, nil);
   m_QQView := PagedView.Create(Self, nil);
   m_KolView := PagedView.Create(Self, nil);
   m_LogRatiosView := PagedView.Create(Self, nil);
   m_Diagrams := TasacsDiagrams.Create(Self);
   m_YearClassView := PagedView.Create(Self, nil);
   m_YearClassNView := PagedView.Create(Self, nil);
   with m_Diagrams do
   begin
      m_StdDiagram := StdDiagram.Create(m_Diagrams, m_Datacontainer);
      for iVar := stdRecruits to stdLandings do
      begin
         m_StdCharts[ord(iVar) - ord(stdRecruits)] := StdVarChart.Create(m_Diagrams, nil, FloatMatrix(m_Datacontainer.StdData[ord(iVar)]).ArrayName, iVar, m_DataContainer);
         (m_StdDiagram as IDiagram).RegisterDiagramTarget(tcomponent(m_StdCharts[ord(iVar) - ord(stdRecruits)]) as IDiagramTarget);
      end;
      m_SSBRecruitsDiagram := TasacsDiagram.Create(m_Diagrams, nil, '', 'SSB and recruits per year', 'Recruit age = ' + inttostr(m_DataContainer.FirstAge), m_DataContainer);
      m_SSBRecruitsChart := SSBRecruitChart.Create(m_Diagrams, nil, 'SSB recruits', m_Datacontainer);
      (m_SSBRecruitsDiagram as IDiagram).RegisterDiagramTarget(m_SSBRecruitsChart as IDiagramTarget);
      for iDs := 0 to m_Datacontainer.DS.count - 1 do
      begin
         // Create Residual charts
         m_ResidualUCharts.Add(ResidualsChart.Create(m_Diagrams, m_DataContainer, iDS, rUnWeighted));
         m_ResidualWCharts.Add(ResidualsChart.Create(m_Diagrams, m_DataContainer, iDS, rWeighted));
         m_ResidualPhiCharts.Add(ResidualsChart.Create(m_Diagrams, m_DataContainer, iDS, rPhi));
         m_ResidualWeightCharts.Add(ResidualsChart.Create(m_Diagrams, m_DataContainer, iDS, rWeight));
         m_ResidualDiagrams.Add(TasacsDiagram.Create(m_Diagrams, nil, DataSourceContainer(m_DataContainer.Ds[iDS]).Key, 'Residuals',
            DataSourceContainer(m_DataContainer.Ds[iDS]).Name, m_DataContainer));
         if iDs > 0 then
            (TComponent(m_ResidualUCharts[0]) as IChart).RegisterChild((TComponent(m_ResidualUCharts[iDs]) as IChart));
         (TComponent(m_ResidualUCharts[0]) as IChart).RegisterChild((TComponent(m_ResidualWCharts[iDs]) as IChart));
         (TComponent(m_ResidualUCharts[0]) as IChart).RegisterChild((TComponent(m_ResidualPhiCharts[iDs]) as IChart));
         (TComponent(m_ResidualUCharts[0]) as IChart).RegisterChild((TComponent(m_ResidualWeightCharts[iDs]) as IChart));
         (TComponent(m_ResidualDiagrams[iDs]) as IDiagram).RegisterDiagramTarget(TComponent(m_ResidualUCharts[iDs]) as IDiagramTarget);
         (TComponent(m_ResidualDiagrams[iDs]) as IDiagram).RegisterDiagramTarget(TComponent(m_ResidualWCharts[iDs]) as IDiagramTarget);
         (TComponent(m_ResidualDiagrams[iDs]) as IDiagram).RegisterDiagramTarget(TComponent(m_ResidualPhiCharts[iDs]) as IDiagramTarget);
         (TComponent(m_ResidualDiagrams[iDs]) as IDiagram).RegisterDiagramTarget(TComponent(m_ResidualWeightCharts[iDs]) as IDiagramTarget);
         (m_ResidualsView as IPagedView).AddView((TComponent(m_ResidualDiagrams[iDs]) as IVisibleNodeComponent).View);

         // Create Log Ratios charts
         m_LogRatiosDiagrams.Add(TasacsDiagram.Create(m_Diagrams, nil, DataSourceContainer(m_DataContainer.Ds[iDS]).Key, 'Log ratios',
            DataSourceContainer(m_DataContainer.Ds[iDS]).Name, m_DataContainer));
         dsc := DataSourceContainer(frmTasacsTrend.m_DataContainer.DS[iDs]);
         NumAges := FloatMatrix(dsc.DsData[ord(dsObs)]).GetSize(2);
         m_LogRatiosCharts.Add(TObjectList.Create);
         for iAge := 0 to NumAges - 1 - 2 do
         begin
            TList(m_LogRatiosCharts[iDs]).Add(LogRatiosChart.Create(m_Diagrams, m_DataContainer, iDS, iAge));
            if not ((iAge = 0) and (iDs = 0)) then
               (TComponent(TList(m_LogRatiosCharts[0])[0]) as IChart).RegisterChild(TComponent(TList(m_LogRatiosCharts[iDs])[iAge]) as IChart);
            (TComponent(m_LogRatiosDiagrams[iDs]) as IDiagram).RegisterDiagramTarget(TComponent(TList(m_LogRatiosCharts[iDs])[iAge]) as IDiagramTarget);
         end;
         (m_LogRatiosView as IPagedView).AddView((TComponent(m_LogRatiosDiagrams[iDs]) as IVisibleNodeComponent).View);

         m_QQCharts.Add(QQChart.Create(m_Diagrams, m_DataContainer, iDS));
         m_QQDiagrams.Add(TasacsDiagram.Create(m_Diagrams, nil, DataSourceContainer(m_DataContainer.Ds[iDS]).Key, 'QQ plot',
            DataSourceContainer(m_DataContainer.Ds[iDS]).Name, m_DataContainer));
         if iDs > 0 then
            (TComponent(m_QQCharts[0]) as IChart).RegisterChild((TComponent(TComponent(m_QQCharts[iDs])) as IChart));
         (TComponent(m_QQDiagrams[iDs]) as IDiagram).RegisterDiagramTarget(TComponent(m_QQCharts[iDs]) as IDiagramTarget) ;
         (m_QQView as IPagedView).AddView((TComponent(m_QQDiagrams[iDs]) as IVisibleNodeComponent).View);

         m_KolCharts.Add(KolChart.Create(m_Diagrams, m_DataContainer, iDS));
         m_KolDiagrams.Add(KolDiagram.Create(m_Diagrams, iDS, m_DataContainer));
         if iDs > 0 then
            (TComponent(m_KolCharts[0]) as IChart).RegisterChild((TComponent(m_KolCharts[iDs]) as IChart));
         (TComponent(m_KolDiagrams[iDs]) as IDiagram).RegisterDiagramTarget(TComponent(m_KolCharts[iDs]) as IDiagramTarget) ;
         (m_KolView as IPagedView).AddView((TComponent(m_KolDiagrams[iDs]) as IVisibleNodeComponent).View);
      end;
      for iDgr := 0 to m_DataContainer.NumYearClassDiagrams - 1 do
      begin
         iCohortFrom := iDgr * m_DataContainer.NumYearClassChartsPerDiagram;
         iCohortTo := (iDgr + 1) * m_DataContainer.NumYearClassChartsPerDiagram - 1;
         DgrCapt := inttostr(m_DataContainer.BirthYearFromCohort[iCohortFrom]) + ' - ' +
            inttostr(m_DataContainer.BirthYearFromCohort[iCohortTo]);
         m_YearClassDiagrams.Add(TasacsDiagram.Create(m_Diagrams, nil, DgrCapt, 'Year class', DgrCapt, m_DataContainer));
         (m_YearClassView as IPagedView).AddView((TComponent(m_YearClassDiagrams[iDgr]) as IVisibleNodeComponent).View);
         m_YearClassNDiagrams.Add(YearClassNDiagram.Create(m_Diagrams, nil, DgrCapt, 'Year class', DgrCapt, m_DataContainer));
         (m_YearClassNView as IPagedView).AddView((TComponent(m_YearClassNDiagrams[iDgr]) as IVisibleNodeComponent).View);
      end;
      for iCohort := 0 to m_DataContainer.NumCohorts - 1 do
      begin
         iDgr := floor(iCohort / m_DataContainer.NumYearClassChartsPerDiagram);
         m_YearClassCharts.Add(YearClassChart.Create(m_Diagrams, m_DataContainer, iCohort));
         m_YearClassNCharts.Add(YearClassNChart.Create(m_Diagrams, m_DataContainer, iCohort, iDgr));
         // Setup Mother Child hierarchy
         if iCohort > 0 then
         begin
            (TComponent(m_YearClassCharts[0]) as IChart).RegisterChild((TComponent(m_YearClassCharts[iCohort]) as IChart));
            (TComponent(m_YearClassNCharts[0]) as IChart).RegisterChild((TComponent(m_YearClassNCharts[iCohort]) as IChart));
         end;
         (TComponent(m_YearClassDiagrams[iDgr]) as IDiagram).RegisterDiagramTarget(TComponent(m_YearClassCharts[iCohort]) as IDiagramTarget);
         (TComponent(m_YearClassNDiagrams[iDgr]) as IDiagram).RegisterDiagramTarget(TComponent(m_YearClassNCharts[iCohort]) as IDiagramTarget);
      end; // for
      m_BootDiagram := BootDiagram.Create(m_Diagrams, m_Datacontainer);
      for iBoot := btSSB to btBanana do
      begin
         m_BootCharts[ord(iBoot) - ord(btSSB)] := BootChart.Create(m_Diagrams, nil, c_BootChartName[iBoot], iBoot, m_DataContainer);
         (m_BootDiagram as IDiagram).RegisterDiagramTarget(tcomponent(m_BootCharts[ord(iBoot) - ord(btSSB)]) as IDiagramTarget);
      end;
      m_RetroDiagram := RetroDiagram.Create(m_Diagrams, m_Datacontainer);
      for iRetro := rtSSB to rtRecruit do
      begin
         m_RetroCharts[ord(iRetro) - ord(rtSSB)] := RetroChart.Create(m_Diagrams, nil, c_RetroChartName[iRetro], iRetro, m_DataContainer);
         (m_RetroDiagram as IDiagram).RegisterDiagramTarget(tcomponent(m_RetroCharts[ord(iRetro) - ord(rtSSB)]) as IDiagramTarget);
      end;
   end; // with

   m_MainTarget := TActionTargetOwnerDelegation.Create(Self);
   m_ActionManager := TActionManager.Create(Self, m_MainTarget, m_Images);
   m_ActionManager.LoadSetup(s_TasacsTrendSetupDoc);
   m_ActionManager.LoadSetup(s_StdCommandSetupDoc);
   m_ActionManager.SetupActionBars(Self);

   UpdatePhase();
end; // TfrmTasacsTrend.FormCreate


destructor TfrmTasacsTrend.Destroy;
begin
   m_DataContainer.Free;
   inherited;
end; // TfrmTasacsTrend.Destroy


procedure TfrmTasacsTrend.Execute(Action : PgDataAction; var Handled, Recurse : Boolean);
begin
   if not Handled then
      case Action.Id of
         ID_SAVECONFIG:
         begin
            SaveConfiguration;
            Handled := true;
         end;
         ID_LOADCONFIG:
         begin
            OpenConfiguration;
            Handled := true;
         end;
         ID_FILE_PRINT_SETUP:
         begin
            printer.ExecuteSetup;
            Handled := true;
         end;
         ID_PRINT, ID_PROPERTIES:
         begin
            (GetActiveView as TActionTarget).Execute(Action, Handled, Recurse);
         end;
         ID_FILE_EXIT:
            if mrYes = MessageDlg('Are you sure you want to exit?', mtConfirmation, [mbYes, mbNo], 0) then
               halt;
      end;
end; // TfrmTasacsTrend.Execute


procedure TfrmTasacsTrend.Update(Action : PgDataAction; var Handled, Recurse : Boolean);
begin
   if not Handled then
      case Action.Id of
         ID_FILE_PRINT_SETUP,
         ID_FILE_EXIT:
         begin
            Action.Enabled := true;
            Handled := true;
         end;
         ID_SAVECONFIG,
         ID_LOADCONFIG,
         ID_FILE_SAVEAS:
         begin
            Action.Enabled := true;
            Handled := true;
         end;
         ID_PRINT,
         ID_PROPERTIES:
         begin
            if not m_handlingUpdate then
            begin
               m_handlingUpdate := true;
               if not Handled then
                  if GetActiveView <> nil then
                     (GetActiveView as TActionTarget).Update(Action, Handled, Recurse);
               m_handlingUpdate := false;
            end;
         end;
      end;
end; // TfrmTasacsTrend.Update


procedure TfrmTasacsTrend.GetContextActions(var ActionIds : TList);
begin
end;


function TfrmTasacsTrend.GetSubTargetCount : Integer;
begin
   Result := 0;
end; // TfrmTasacsTrend.GetSubTargetCount


function TfrmTasacsTrend.GetSubTarget(I : Integer) : TActionTarget;
begin
   Result := nil;
end; // TfrmTasacsTrend.GetSubTarget


function TfrmTasacsTrend.GetActiveView : TView;
begin
   Result := nil;
   if (not (csDestroying in ComponentState)) and (tvPlotType.Selected <> nil) then
      case tvPlotType.Selected.Index of
         0: if Assigned(m_Diagrams.m_StdDiagram) then
               Result := (m_Diagrams.m_StdDiagram as IVisibleNodeComponent).View;
         1: if Assigned(m_Diagrams.m_SSBRecruitsDiagram) then
               Result := (m_Diagrams.m_SSBRecruitsDiagram as IVisibleNodeComponent).View;
         2: if Assigned(m_ResidualsView) then
               Result := m_ResidualsView;
         3: if Assigned(m_LogRatiosView) then
               Result := m_LogRatiosView;
         4: if Assigned(m_QQView) then
               Result := m_QQView;
         5: if Assigned(m_KolView) then
               Result := m_KolView;
         6: if Assigned(m_YearClassView) then
               Result := m_YearClassView;
         7: if Assigned(m_YearClassNView) then
               Result := m_YearClassNView;
         8: if Assigned(m_Diagrams.m_BootDiagram) then
               Result := (m_Diagrams.m_BootDiagram as IVisibleNodeComponent).View;
         9: if Assigned(m_Diagrams.m_RetroDiagram) then
               Result := (m_Diagrams.m_RetroDiagram as IVisibleNodeComponent).View;
      end; // case
end; // TfrmTasacsTrend.GetActiveView


function TfrmTasacsTrend.GetExtentMapper : TExtentMapper;
begin
   Result := m_ExtentMapper;
end; // TfrmTasacsTrend.GetExtentMapper


function TfrmTasacsTrend.GetWorkspaceTopLeft(Control : TControl) : TPoint;
begin
   Result := point(0, 0);
end; // TfrmTasacsTrend.GetWorkspaceBounds


function TfrmTasacsTrend.GetActionManager : IActionManager;
begin
   Result := m_ActionManager as IActionManager;
end; // TfrmTasacsTrend.GetActionManager


function TfrmTasacsTrend.GetImages : TImageList;
begin
   Result := m_Images;
end; // TfrmTasacsTrend.GetImages


procedure TfrmTasacsTrend.OnVisibleNodeUpdated(VisibleNodeComponent : IVisibleNodeComponent);
begin
end; // TfrmTasacsTrend.OnVisibleNodeUpdated


procedure TfrmTasacsTrend.OnVisibleNodeDeleted(VisibleNodeComponent, ParentNodeComponent : IVisibleNodeComponent);
begin
end; // TfrmTasacsTrend.OnVisibleNodeDeleted


procedure TfrmTasacsTrend.OnViewableComponentAdded(ViewComponent, ViewParent : IVisibleNodeComponent; UserSelectName : Boolean = false);
begin
end; // TfrmTasacsTrend.OnViewableComponentAdded


const s_Diagrams = 'Diagrams';


procedure TfrmTasacsTrend.SaveConfiguration;
var
   FileStream : TFileStream;
   Doc : TXMLDocument;
begin
   if IFMCreateSaveDialog(Self, m_ConfigFile, 'Save configuration as', ConfigFileFilter, s_ConfigExt) then
   begin
      FileStream := TFileStream.Create(m_ConfigFile, fmCreate);
      Doc := TXMLDocument.Create(Self);
      Doc.DOMVendor := XercesDOM;
      Doc.Active := true;
      SaveChild(Doc, m_Diagrams, s_Diagrams);
      Doc.SaveToStream(FileStream);
      FileStream.Free;
      Doc.Free;
   end;
end; // TfrmTasacsTrend.SaveConfiguration


procedure TfrmTasacsTrend.OpenConfiguration;
var
   FileStream : TFileStream;
   Doc : TXMLDocument;
//   GraphNode : IXMLNode;
begin
   if IFMCreateOpenDialog(Self, m_ConfigFile, 'Open configuration', ConfigFileFilter, s_ConfigExt) then
   begin
      FileStream := TFileStream.Create(m_ConfigFile, fmOpenRead);
      Doc := TXMLDocument.Create(Self);
      Doc.DOMVendor := XercesDOM;
      Doc.LoadFromStream(FileStream);
      OpenChild(Doc, m_Diagrams, s_Diagrams);
      FileStream.Free;
      Doc.Free;
      UpdatePhase;
   end;
end; // TfrmTasacsTrend.OpenConfiguration


procedure TfrmTasacsTrend.FrmPanelResize(Sender: TObject);
begin
   if GetActiveView <> nil then
      GetActiveView.Onresize;
end;


procedure TfrmTasacsTrend.UpdatePhase();
var
   iVar : StdVar;
   iBoot : TBootType;
   iRetro : TRetroType;
   iDs, iAge, NumAges, iCohort : Integer;
   dsc : DataSourceContainer;
begin
   if m_RunDir = '' then
      exit;
   if (tvPlotType.Selected <> nil) and (tvPlotType.Selected.Index >= 0) then
   begin
      with m_Diagrams do
      begin
         (m_StdDiagram as IVisibleNodeComponent).View.AttachParent(nil);
         (m_SSBRecruitsDiagram as IVisibleNodeComponent).View.AttachParent(nil);
         m_ResidualsView.AttachParent(nil);
         m_LogRatiosView.AttachParent(nil);
         (m_BootDiagram as IVisibleNodeComponent).View.AttachParent(nil);
         (m_RetroDiagram as IVisibleNodeComponent).View.AttachParent(nil);
         case tvPlotType.Selected.Index of
            0:
            begin
               for iVar := stdRecruits to stdLandings do
                  (tcomponent(m_StdCharts[ord(iVar) - ord(stdRecruits)]) as IChart).SetupSeries;
               with (m_StdDiagram as IVisibleNodeComponent).View do
               begin
                  AttachParent(FrmPanel);
                  Repaint;
               end;
            end;
            1:
            begin
               (m_SSBRecruitsChart as IChart).SetupSeries;
               with (m_SSBRecruitsDiagram as IVisibleNodeComponent).View do
               begin
                  AttachParent(FrmPanel);
                  Repaint;
               end;
            end;
            2:
            begin
               for iDs := 0 to m_Datacontainer.DS.count - 1 do
               begin
                  (TComponent(m_ResidualUCharts[iDs]) as IChart).SetupSeries;
                  (TComponent(m_ResidualWCharts[iDs]) as IChart).SetupSeries;
                  (TComponent(m_ResidualPhiCharts[iDs]) as IChart).SetupSeries;
                  (TComponent(m_ResidualWeightCharts[iDs]) as IChart).SetupSeries;
               end;
               m_ResidualsView.AttachParent(nil);
               m_ResidualsView.AttachParent(FrmPanel);
            end;
            3:
            begin
               for iDs := 0 to m_Datacontainer.DS.count - 1 do
               begin
                  dsc := DataSourceContainer(frmTasacsTrend.m_DataContainer.DS[iDs]);
                  NumAges := FloatMatrix(dsc.DsData[ord(dsObs)]).GetSize(2);
                  for iAge := 0 to NumAges - 1 - 2 do
                     (TComponent(TList(m_LogRatiosCharts[iDs])[iAge]) as IChart).SetupSeries;
               end;
               m_LogRatiosView.AttachParent(nil);
               m_LogRatiosView.AttachParent(FrmPanel);
            end;
            4:
            begin
               for iDs := 0 to m_Datacontainer.DS.count - 1 do
               begin
                  (TComponent(m_QQCharts[iDs]) as IChart).SetupSeries;
                  (TComponent(m_QQCharts[iDs]) as IChart).SetupSeries;
               end;
               m_QQView.AttachParent(nil);
               m_QQView.AttachParent(FrmPanel);
            end;
            5:
            begin
               for iDs := 0 to m_Datacontainer.DS.count - 1 do
               begin
                  (TComponent(m_KolCharts[iDs]) as IChart).SetupSeries;
                  (TComponent(m_KolCharts[iDs]) as IChart).SetupSeries;
               end;
               m_KolView.AttachParent(nil);
               m_KolView.AttachParent(FrmPanel);
            end;
            6:
            begin
               for iCohort := 0 to m_Datacontainer.DS.count - 1 do
               begin
                  (TComponent(m_YearClassCharts[iCohort]) as IChart).SetupSeries;
                  (TComponent(m_YearClassCharts[iCohort]) as IChart).SetupSeries;
               end;
               m_YearClassView.AttachParent(nil);
               m_YearClassView.AttachParent(FrmPanel);
            end;
            7:
            begin
               for iCohort := 0 to m_Datacontainer.DS.count - 1 do
               begin
                  (TComponent(m_YearClassNCharts[iCohort]) as IChart).SetupSeries;
                  (TComponent(m_YearClassNCharts[iCohort]) as IChart).SetupSeries;
               end;
               m_YearClassNView.AttachParent(nil);
               m_YearClassNView.AttachParent(FrmPanel);
            end;
            8:
            begin
               for iBoot := btSSB to btBanana do
                  (tcomponent(m_BootCharts[ord(iBoot) - ord(btSSB)]) as IChart).SetupSeries;
               with (m_BootDiagram as IVisibleNodeComponent).View do
               begin
                  AttachParent(FrmPanel);
                  Repaint;
               end;
            end;
            9:
            begin
               for iRetro := rtSSB to rtRecruit do
                  (tcomponent(m_RetroCharts[ord(iRetro) - ord(rtSSB)]) as IChart).SetupSeries;
               with (m_RetroDiagram as IVisibleNodeComponent).View do
               begin
                  AttachParent(FrmPanel);
                  Repaint;
               end;
            end;
         end; // case
      end;
   end;
end; // TfrmTasacsTrend.UpdatePhase


procedure TfrmTasacsTrend.tvPlotTypeClick(Sender: TObject);
begin
   UpdatePhase();
end;

end.
